/*
 * Copyright 2006 Matt Jensen
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations under the License.
 */
package org.spectaql.hibernate;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.spectaql.PersistenceAdapter;
import org.spectaql.internal.hibernate.HibernateUtils;
import org.spectaql.metadata.PersistenceMetadata;
import org.hibernate.SessionFactory;
import org.hibernate.Session;

/**
 * <p>
 * <code>HibernatePersistenceMetadataSource</code> is an implementation of the {@link PersistenceAdapter}
 * interface which obtains O/R mapping information from a Hibernate session.
 * </p>
 * <p>
 * <strong>Thread Safety:</strong> Instances of this class are thread safe. 
 * </p>
 */
public class HibernatePersistenceAdapter implements PersistenceAdapter
{
    private static Log LOG = LogFactory.getLog(HibernatePersistenceAdapter.class);

    /**
     * <p>
     * The persistence metadata. 
     * </p>
     */
    private final PersistenceMetadata m_persistenceMetadata;

    /**
     * <p>
     * Construct a {@link HibernatePersistenceAdapter} instance.
     * </p>
     *
     * @param sessionFactory the session factory.
     */
    public HibernatePersistenceAdapter(final SessionFactory sessionFactory)
    {
        super();
        assert null != sessionFactory : "The [sessionFactory] argument cannot be null.";

        m_persistenceMetadata = createPersistenceMetadata(sessionFactory);
    }

    /* inherit javadoc */
    public PersistenceMetadata getPersistenceMetadata()
    {
        return m_persistenceMetadata;
    }

    /**
     * <p>
     * Create the {@link PersistenceMetadata} instance by examining the mappings associated with a given session
     * factory.
     * </p>
     *
     * @param sessionFactory the session factory.
     * @return {@link PersistenceMetadata} instance.
     */
    private PersistenceMetadata createPersistenceMetadata(final SessionFactory sessionFactory)
    {
        final PersistenceMetadata result;
        final Session session = sessionFactory.openSession();
        try
        {
            result = HibernateUtils.createPersistenceMetadata(session);
        }
        finally
        {
            session.close();
        }
        return result;
    }
}
